#include<iostream>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<pthread.h>
#include<cstring>
#include<cctype> //toupper函数，小写转大写
#include<netinet/in.h>  //sockaddr_in 结构体
using namespace std;
#define SERVER_PORT 8080
void * handleClientInof(void * arg)
 {
    //线程分离
     pthread_detach(pthread_self());
     // 通信的文件描述符
     int connfd = *(int *)arg;
     // 读取客户端发送数据的缓冲区
     char buffer[1024] = {0};

     int readBytes = 0;
     while (1)
     {
         readBytes = read(connfd, buffer, sizeof(buffer));
         if (readBytes < 0)
         {
             cout << "readBytes<0" << endl;
             break;
         }
         else if (readBytes == 0)
         {
             // 客户端断开连接
             cout << "readBytes=0" << endl;
             break;
         }
         else
         {
             cout << "buffer:" << buffer << endl;
             for (int i = 0; i < readBytes; i++)
             {
                 buffer[i] = toupper(buffer[i]);
             }
             write(connfd, buffer, readBytes);
         }
        }
    //释放资源
    close(connfd);
    //线程退出
     pthread_exit(NULL);
 }
int main()
{
    //创建套接字
    int sockfd=socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd==-1)
    {
        perror("socked error");
        _exit(-1);
    }
    //绑定IP和端口
    struct sockaddr_in localAddress;
    memset(&localAddress, 0, sizeof(localAddress));
    //地址族
    localAddress.sin_family = AF_INET;
    localAddress.sin_port =htons(SERVER_PORT);
    localAddress.sin_addr.s_addr =htonl(INADDR_ANY);
    //设置端口复用
    int optVal = 1;
    int ret=setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optVal,sizeof(optVal));
    if(ret!=0)
    {
        perror("bind error:");
        _exit(-1);
    }
    // 绑定
    ret=bind(sockfd, reinterpret_cast <const sockaddr*>(&localAddress), sizeof(localAddress));
    if(ret!=0)
    {
        perror("bind error:");
        _exit(-1);
    }
    //给监听的套接字设置监听
    ret=listen(sockfd, 10);
    if(ret!=0)
    {
        perror("listen error:");
        _exit(-1);
    }
    int connfd = 0;

    while (1)
    {
        //accept接受客户端连接，接受到新的客户端连接就解除阻塞
        connfd=accept(sockfd,NULL,NULL);
        if(connfd==-1)
        {
            perror("accept error!");
            _exit(-1);
        }
        //程序到达这个地方：就需要单独开辟线程去处理客户端的数据通信

        //创建一个新线程
        pthread_t threadId;
        ret=pthread_create(&threadId, NULL, handleClientInof, (void*)&connfd);
        if(ret!=0)
        {
            perror("create thread:");
            _exit(-1);
        }
        //使connfd一定能够接受成功并传入
        sleep(1);
    }

    //释放资源
    close(connfd);
    // 关闭文件描述符
    close(sockfd);

    return 0;
}